public class Renderer2D extends NodeSub {
	public static int bottomX;
	public static int bottomY;
	public static int endX;
	public static int middleX;
	public static int centerY;
	public static int height;
	public static int pixels[];
	public static int topX;
	public static int topY;
	public static int width;

	public static void setDefaultDrawingAreaSize() {
		Renderer2D.topX = 0;
		Renderer2D.topY = 0;
		Renderer2D.bottomX = Renderer2D.width;
		Renderer2D.bottomY = Renderer2D.height;
		Renderer2D.endX = Renderer2D.bottomX;
		Renderer2D.middleX = Renderer2D.bottomX / 2;
	}

	/**
	 * Draws a rectangle shape.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width.
	 * @param height
	 *            The height.
	 * @param color
	 *            The color.
	 */
	public static void fillRectangle(int x, int y, int width, int height, int color) {
		if (x < Renderer2D.topX) {
			width -= Renderer2D.topX - x;
			x = Renderer2D.topX;
		}
		if (y < Renderer2D.topY) {
			height -= Renderer2D.topY - y;
			y = Renderer2D.topY;
		}
		if (x + width > Renderer2D.bottomX) {
			width = Renderer2D.bottomX - x;
		}
		if (y + height > Renderer2D.bottomY) {
			height = Renderer2D.bottomY - y;
		}
		int k1 = Renderer2D.width - width;
		int l1 = x + y * Renderer2D.width;
		for (int i2 = -height; i2 < 0; i2++) {
			for (int j2 = -width; j2 < 0; j2++) {
				Renderer2D.pixels[l1++] = color;
			}
			l1 += k1;
		}
	}

	public static void fillPixels(int i, int j, int k, int l, int i1) {
		Renderer2D.drawHorizontalLine(i, i1, j, l);
		Renderer2D.drawHorizontalLine(i, (i1 + k) - 1, j, l);
		Renderer2D.drawVerticalLine(i, i1, k, l);
		Renderer2D.drawVerticalLine((i + j) - 1, i1, k, l);
	}

	public static void init(int width, int height, int pixels[]) {
		Renderer2D.pixels = pixels;
		Renderer2D.width = width;
		Renderer2D.height = height;
		Renderer2D.setDrawingArea(0, 0, width, height);
	}

	/**
	 * Fills a rectangle, with alpha.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width.
	 * @param height
	 *            The height.
	 * @param color
	 *            The color.
	 * @param alpha
	 *            The opacity.
	 */
	public static void fillRectangle(int x, int y, int width, int height, int color, int alpha) {
		if (x < Renderer2D.topX) {
			width -= Renderer2D.topX - x;
			x = Renderer2D.topX;
		}
		if (y < Renderer2D.topY) {
			height -= Renderer2D.topY - y;
			y = Renderer2D.topY;
		}
		if (x + width > Renderer2D.bottomX) {
			width = Renderer2D.bottomX - x;
		}
		if (y + height > Renderer2D.bottomY) {
			height = Renderer2D.bottomY - y;
		}
		int srcAlpha = 256 - alpha;
		int destRed = (color >> 16 & 0xff) * alpha;
		int destGreen = (color >> 8 & 0xff) * alpha;
		int destBlue = (color & 0xff) * alpha;
		int step = Renderer2D.width - width;
		int offset = x + y * Renderer2D.width;
		for (int i4 = 0; i4 < height; i4++) {
			for (int j4 = -width; j4 < 0; j4++) {
				int l2 = (Renderer2D.pixels[offset] >> 16 & 0xff) * srcAlpha;
				int i3 = (Renderer2D.pixels[offset] >> 8 & 0xff) * srcAlpha;
				int j3 = (Renderer2D.pixels[offset] & 0xff) * srcAlpha;
				int k4 = ((destRed + l2 >> 8) << 16) + ((destGreen + i3 >> 8) << 8)
				+ (destBlue + j3 >> 8);
				Renderer2D.pixels[offset++] = k4;
			}
			offset += step;
		}
	}

	/**
	 * Draws a box with borders only.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width.
	 * @param height
	 *            The height.
	 * @param color
	 *            The color.
	 * @param alpha
	 *            The alpha.
	 */
	public static void drawUnfilledBox(int x, int y, int width, int height, int color, int alpha) {
		Renderer2D.drawHorizontalLine(x, y, width, color, alpha);
		Renderer2D.drawHorizontalLine(x, (y + height) - 1, width, color, alpha);
		if (height >= 3) {
			Renderer2D.drawVerticalLine(x, y + 1, height - 2, color, alpha);
			Renderer2D.drawVerticalLine((x + width) - 1, y + 1, height - 2, color, alpha);
		}
	}

	/**
	 * Draws a horizontal line.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width.
	 * @param color
	 *            The color.
	 */
	public static void drawHorizontalLine(int x, int y, int width, int color) {
		if ((y < Renderer2D.topY) || (y >= Renderer2D.bottomY)) {
			return;
		}
		if (x < Renderer2D.topX) {
			width -= Renderer2D.topX - x;
			x = Renderer2D.topX;
		}
		if (x + width > Renderer2D.bottomX) {
			width = Renderer2D.bottomX - x;
		}
		int i1 = x + y * Renderer2D.width;
		for (int j1 = 0; j1 < width; j1++) {
			Renderer2D.pixels[i1 + j1] = color;
		}
	}

	/**
	 * Draws a horizontal line with alpha.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width.
	 * @param color
	 *            The color.
	 * @param alpha
	 *            The alpha.
	 */
	public static void drawHorizontalLine(int x, int y, int width, int color, int alpha) {
		if ((y < Renderer2D.topY) || (y >= Renderer2D.bottomY)) {
			return;
		}
		if (x < Renderer2D.topX) {
			width -= Renderer2D.topX - x;
			x = Renderer2D.topX;
		}
		if (x + width > Renderer2D.bottomX) {
			width = Renderer2D.bottomX - x;
		}
		int srcAlpha = 256 - alpha;
		int destRed = (color >> 16 & 0xff) * alpha;
		int destGreen = (color >> 8 & 0xff) * alpha;
		int destBlue = (color & 0xff) * alpha;
		int step = x + y * Renderer2D.width;
		for (int j3 = 0; j3 < width; j3++) {
			int j2 = (Renderer2D.pixels[step] >> 16 & 0xff) * srcAlpha;
			int k2 = (Renderer2D.pixels[step] >> 8 & 0xff) * srcAlpha;
			int l2 = (Renderer2D.pixels[step] & 0xff) * srcAlpha;
			int k3 = ((destRed + j2 >> 8) << 16) + ((destGreen + k2 >> 8) << 8)
			+ (destBlue + l2 >> 8);
			Renderer2D.pixels[step++] = k3;
		}
	}

	/**
	 * Draws a vertical line.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width.
	 * @param color
	 *            The color.
	 */
	public static void drawVerticalLine(int x, int y, int height, int color) {
		if ((x < Renderer2D.topX) || (x >= Renderer2D.bottomX)) {
			return;
		}
		if (y < Renderer2D.topY) {
			height -= Renderer2D.topY - y;
			y = Renderer2D.topY;
		}
		if (y + height > Renderer2D.bottomY) {
			height = Renderer2D.bottomY - y;
		}
		int j1 = x + y * Renderer2D.width;
		for (int k1 = 0; k1 < height; k1++) {
			Renderer2D.pixels[j1 + k1 * Renderer2D.width] = color;
		}
	}

	/**
	 * Draws a vertical line with alpha.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width.
	 * @param color
	 *            The color.
	 * @param alpha
	 *            The alpha.
	 */
	private static void drawVerticalLine(int x, int y, int height, int color, int alpha) {
		if ((x < Renderer2D.topX) || (x >= Renderer2D.bottomX)) {
			return;
		}
		if (y < Renderer2D.topY) {
			height -= Renderer2D.topY - y;
			y = Renderer2D.topY;
		}
		if (y + height > Renderer2D.bottomY) {
			height = Renderer2D.bottomY - y;
		}
		int srcAlpha = 256 - alpha;
		int destRed = (color >> 16 & 0xff) * alpha;
		int destGreen = (color >> 8 & 0xff) * alpha;
		int destBlue = (color & 0xff) * alpha;
		int step = x + y * Renderer2D.width;
		for (int offsetY = 0; offsetY < height; offsetY++) {
			int srcRed = (Renderer2D.pixels[step] >> 16 & 0xff) * srcAlpha;
			int srcGreen = (Renderer2D.pixels[step] >> 8 & 0xff) * srcAlpha;
			int srcBlue = (Renderer2D.pixels[step] & 0xff) * srcAlpha;
			int destColor = ((destRed + srcRed >> 8) << 16) + ((destGreen + srcGreen >> 8) << 8)
			+ (destBlue + srcBlue >> 8);
			Renderer2D.pixels[step] = destColor;
			step += Renderer2D.width;
		}
	}

	/**
	 * AKA setAllPixelsToZero. The real function is just to clear them :)
	 */
	public static void clearPixels() {
		int i = Renderer2D.width * Renderer2D.height;
		for (int j = 0; j < i; j++) {
			Renderer2D.pixels[j] = 0;
		}
	}

	/**
	 * Sets the drawing area parameters.
	 * 
	 * @param x
	 *            The x position.
	 * @param y
	 *            The y position.
	 * @param width
	 *            The width, determines how wide the rendered image is.
	 * @param height
	 *            The height, determines how tall the rendered image is.
	 */
	public static void setDrawingArea(int x, int y, int width, int height) {
		if (x < 0) {
			x = 0;
		}
		if (y < 0) {
			y = 0;
		}
		if (width > Renderer2D.width) {
			width = Renderer2D.width;
		}
		if (height > Renderer2D.height) {
			height = Renderer2D.height;
		}
		Renderer2D.topX = x;
		Renderer2D.topY = y;
		Renderer2D.bottomX = width;
		Renderer2D.bottomY = height;
		Renderer2D.endX = Renderer2D.bottomX;
		Renderer2D.middleX = Renderer2D.bottomX / 2;
		Renderer2D.centerY = Renderer2D.bottomY / 2;
	}

	Renderer2D() {
	}
}
